package com.demo.nio.ByteBuffer;


import lombok.extern.slf4j.Slf4j;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.charset.StandardCharsets;

@Slf4j
public class BasicByteBuffer {

    public static void main(String[] args) throws IOException {
        test4();
    }

    public static void test1() {
        try (FileChannel channel = new FileInputStream("data.txt").getChannel()) {
            ByteBuffer buffer = ByteBuffer.allocate(10);
            //此时buffer 在输入
            while (channel.read(buffer) != -1) {
                //切换 buffer 为输出
                buffer.flip();
                while (buffer.hasRemaining()) {
                    System.out.print((char) buffer.get());
                }
                //清空缓冲区
                buffer.clear();
            }
        } catch (IOException e) {

        }
    }

    //分散读取
    public static void test2() {
        try (FileChannel channel = new RandomAccessFile("words.txt", "r").getChannel()) {
            //当知道 文件里内容长度 时，可以将内容分散读取
            ByteBuffer buffer1 = ByteBuffer.allocate(3);
            ByteBuffer buffer2 = ByteBuffer.allocate(3);
            ByteBuffer buffer3 = ByteBuffer.allocate(5);
            channel.read(new ByteBuffer[]{buffer1, buffer2, buffer3});
            //注意切换为输出 -> 读模式
            buffer1.flip();
            buffer2.flip();
            buffer3.flip();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    //集中写入
    public static void test3() {
        ByteBuffer hello = StandardCharsets.UTF_8.encode("hello");
        ByteBuffer world = StandardCharsets.UTF_8.encode("world");
        ByteBuffer ch = StandardCharsets.UTF_8.encode("你好");
        try (FileChannel channel = new RandomAccessFile("words2.txt", "rw").getChannel()) {
            channel.write(new ByteBuffer[]{hello, world, ch});
        } catch (IOException e) {

        }
    }

    //处理黏包问题
    public static void test4() {
        ByteBuffer source = ByteBuffer.allocate(50);
        source.put("Hello World!!!\nWha".getBytes(StandardCharsets.UTF_8));
        split(source);
        source.put("t about u?\n".getBytes(StandardCharsets.UTF_8));
        split(source);
    }

    private static void split(ByteBuffer source) {
        ByteBuffer target = null;
        source.flip();
        for (int i = 0; i < source.limit(); i++) {
            if (source.get(i) == '\n') {
                int length = i + 1 - source.position();
                target = ByteBuffer.allocate(length);
                for (int j = 0; j < length; j++) {
                    target.put(source.get());
                }
                target.flip();
                while (target.hasRemaining()) {
                    System.out.print((char) target.get());
                }
            }
        }
        //精妙之处在于 get(i) 不会移动position, get()会
        source.compact();
    }
}
